package com.dkm.orproject.dkmoa.service.serviceimpl.flow;

import com.dkm.orproject.dkmoa.dao.*;
import com.dkm.orproject.dkmoa.domain.*;
import com.dkm.orproject.dkmoa.service.flow.OaGradeFlowService;
import com.dkm.orproject.utils.utils.IdToobtainUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 *  @ClassName : OaGradeFlowServiceImpl  //类名
 *  @Description :   //描述
 *  @Author : 石智诚  //作者
 *  @Date: 2020-10-10 16:31  //时间
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class  OaGradeFlowServiceImpl implements OaGradeFlowService {
    /**
     * 定级Mapper
     */
    @Resource
    OaGradeFlowMapper oaGradeFlowMapper;
    /**
     * 流程记录日志
     */
    @Resource
    OaFlowScheduleMapper flowScheduleMapper;
    /**
     * 通知Mapper
     */
    @Resource
    OaMessageMapper messageMapper;
    /**
     * 通知人员关联Mapper
     */
    @Resource
    OaInformMapper informMapper;
    /**
     * 人员Mapper
     */
    @Resource
    OaPersonnelMapper personnelMapper;
    /**
     * 部门Mapper
     */
    @Resource
    OaDepartmentMapper departmentMapper;
   /**
     * id 工具类
     */
    @Resource
    IdToobtainUtils idToobtainUtils;
    /**
     * 起草流程
     */
    static final Long GRADE_START = 766241579101990912L;
    /**
     * 行政部填写流程
     */
    static final Long GRADE_WRITE = 767757551478648832L;
    /**
     * 部门审核流程
     */
    static final Long GRADE_DEPART = 766242399931478016L;
    /**
     * 人事审核流程
     */
    static final Long GRADEDE_STAFFING = 766244332876476416L;
    /**
     * 总经理审核流程
     */
    static final Long GRADEDE_EXECUTIVE = 766244549545832448L;
    /**
     * 结束流程
     */
    static final Long GRADEDE_END = 766244670828326912L;

    @Override
    public int deleteByPrimaryKey(Long pkGradeId) {
        return oaGradeFlowMapper.deleteByPrimaryKey(pkGradeId);
    }

    @Override
    public int deleteByAll(List<Long> list) {
        return oaGradeFlowMapper.deleteAll(list);
    }


    @Override
    public OaGradeFlow selectByPrimaryKey(Long pkGradeId) {
        return oaGradeFlowMapper.selectByPrimaryKey(pkGradeId);
    }

    @Override
    public int updateByPrimaryKey(OaGradeFlow record) {
        return oaGradeFlowMapper.update(record);
    }

    @Override
    public List<OaGradeFlow> findAll(OaGradeFlow gradeFlow, Integer page, Integer limit, String startTime, String endTime) {
        PageHelper.startPage(page, limit);
        return oaGradeFlowMapper.findAll(gradeFlow, startTime, endTime);
    }

    @Override
    public Long rowCount(OaGradeFlow gradeFlow, String startTime, String endTime) {
        return oaGradeFlowMapper.rowCount(gradeFlow, startTime, endTime);
    }

    /**
     * 起草定级流程
     *
     * @param record 定级模型
     * @return 成功的数量
     */
    @Override
    public int insert(OaGradeFlow record, OaPersonnel personnel) {
        // 创建人
        record.setCreatedBy(personnel.getPersonnelName());
        // 创建定级流程名
        record.setGradeName(personnel.getPersonnelName() + "的定级流程");
        // w为行政部填写
        record.setIsRevision("W");
        // 进度设置为行政部填写
        record.setGradeSchedule(GRADE_WRITE);

        if (record.getPkGradeId() == null) {
            //生成定级ID
            record.setPkGradeId(idToobtainUtils.getNumberId());
            // 流程记录
            OaFlowSchedule flowSchedule = new OaFlowSchedule();
            // 流程记录ID
            flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
            // 起草id
            flowSchedule.setFlowId(GRADE_START);
            // 绑定表单
            flowSchedule.setFormId(record.getPkGradeId());
            // 人员id
            flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
            // 创建人
            flowSchedule.setCreatedBy(personnel.getPersonnelName());
            // 新增薪资定级记录
            flowScheduleMapper.insertSelective(flowSchedule);
            // 删除多余的通知
            messageMapper.deleteByFormId(record.getPkGradeId());
            OaMessage message = new OaMessage();
            // 通知地址
            message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
            // 通知id
            message.setPkMessageId(idToobtainUtils.getNumberId());
            addMeassge(message, personnel.getPersonnelName(), record.getPkGradeId(),
                    record.getGradeName(), "2");
            // 查询部具有行政填写的人
            List<Long> list = personnelMapper.selectByHover("FRONT_WRITE");
            findPersons(list, message);
            return oaGradeFlowMapper.insert(record);
        } else {
            //流程记录
            OaFlowSchedule flowSchedule = new OaFlowSchedule();
            //流程记录ID
            flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
            //起草id
            flowSchedule.setFlowId(GRADE_WRITE);
            //绑定表单
            flowSchedule.setFormId(record.getPkGradeId());
            // 人员id
            flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
            //创建人
            flowSchedule.setCreatedBy(personnel.getPersonnelName());
            //新增薪资定级记录
            flowScheduleMapper.insertSelective(flowSchedule);
            //删除多余的通知
            messageMapper.deleteByFormId(record.getPkGradeId());
            OaMessage message = new OaMessage();
            //通知地址
            message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
            //通知id
            message.setPkMessageId(idToobtainUtils.getNumberId());
            //2为待办
            addMeassge(message, personnel.getPersonnelName(), record.getPkGradeId(),
                    record.getGradeName(), "2");
            //查询部门领导
            // 查询人事领导
            List<Long> list = personnelMapper.selectByHover("FRONT_WRITE");
            findPersons(list, message);
            return oaGradeFlowMapper.update(record);
        }
    }

    /**
     * 行政部填写
     *
     * @param gradeFlow 定级流程
     * @param personnel 操作人
     * @return 成功的数量
     */
    @Override
    public int staffingWrite(OaGradeFlow gradeFlow, OaPersonnel personnel) {
        // D为部门领导审核
        gradeFlow.setIsRevision("D");
        // 进度设置为部门负责人审核
        gradeFlow.setGradeSchedule(GRADE_DEPART);
        //执行语句
        int row=oaGradeFlowMapper.update(gradeFlow);
        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录ID
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 行政部流程Id
        flowSchedule.setFlowId(GRADE_WRITE);
        // 绑定表单
        flowSchedule.setFormId(gradeFlow.getPkGradeId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 创建人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资定级记录
        flowScheduleMapper.insertSelective(flowSchedule);
        // 删除多余的通知
        messageMapper.deleteByFormId(gradeFlow.getPkGradeId());
        OaMessage message = new OaMessage();
        // 通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        // 通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId(),
                flow.getGradeName(), "2");
        OaPersonnel oaPersonnel = personnelMapper.selectByPersonId(gradeFlow.getPersonnelId());
        // 查询部门领导
        Long id = departmentMapper.selectByPrimaryKey(oaPersonnel.getPkDepartmentId()).getPersonnelId();
        noPass(id, message.getPkMessageId());
        return row;
    }

    /**
     * 部门领导审核
     *
     * @param gradeFlow 定级ID
     * @param personnel 人员名字
     * @return 成功的数量
     */
    @Override
    public int departmentPass(OaGradeFlow gradeFlow, OaPersonnel personnel) {
        //S为行政部审核
        gradeFlow.setIsRevision("S");
        // 进度设置为行政部审核
        gradeFlow.setGradeSchedule(GRADEDE_STAFFING);
        int row=oaGradeFlowMapper.update(gradeFlow);
        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程流程ID 部门审核节点
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 薪资流程ID
        flowSchedule.setFlowId(GRADE_DEPART);
        // 绑定表单
        flowSchedule.setFormId(gradeFlow.getPkGradeId());
        // 人员ID
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason(" ");
        // 审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资交接流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        // 删除多余的通知
        messageMapper.deleteByFormId(flow.getPkGradeId());

        OaMessage message = new OaMessage();
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        // id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId()
                , flow.getGradeName(), "2");
        // 根据流程ID 查询人员
        List<Long> longs = personnelMapper.selectByHover("FRONT_STAFF");
        // 新建关联
        findPersons(longs, message);
        return row;
    }

    @Override
    public int departmentNoPass(OaGradeFlow gradeFlow, OaPersonnel personnel, String formReason) {
        // 又回到起点
        gradeFlow.setIsRevision("W");
        // 进度设置为起点审核
        gradeFlow.setGradeSchedule(GRADE_WRITE);

        int row=oaGradeFlowMapper.update(gradeFlow);

        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程流程ID 部门审核节点
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 薪资流程ID
        flowSchedule.setFlowId(GRADE_DEPART);
        // 绑定表单
        flowSchedule.setFormId(gradeFlow.getPkGradeId());
        // 人员ID
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        // 审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资交接流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        // 删除多余的通知
        messageMapper.deleteByFormId(gradeFlow.getPkGradeId());
        OaMessage message = new OaMessage();
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        // id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId(),
                flow.getGradeName(), "0");
        // 根据流程ID 查询人员
        noPass(flow.getPersonnelId(),message.getPkMessageId());
        // 新建关联
        return row;
    }

    /**
     * 行政部通过
     *
     * @param gradeFlow 定级ID
     * @param personnel 操作人
     * @return 成功的数量
     */
    @Override
    public int staffingPass(OaGradeFlow gradeFlow, OaPersonnel personnel) {
        //X为总经理审核
        gradeFlow.setIsRevision("X");
        // 进度设置为总经理审核
        gradeFlow.setGradeSchedule(GRADEDE_EXECUTIVE);

        int row=oaGradeFlowMapper.update(gradeFlow);
        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 薪资流程ID
        flowSchedule.setFlowId(GRADEDE_STAFFING);
        // 流程流程ID 部门审核节点
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 绑定表单
        flowSchedule.setFormId(gradeFlow.getPkGradeId());
        // 人员ID
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("");
        // 审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资交接流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        // 删除多余的通知
        messageMapper.deleteByFormId(gradeFlow.getPkGradeId());
        OaMessage message = new OaMessage();
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        // id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId()
                , flow.getGradeName(), "2");
        // 根据流程ID 查询人员
        List<Long> personIds = personnelMapper.selectByHover("FRONT_GME");
        findPersons(personIds, message);
        // 新建关联
        return row;
    }

    /**
     * 行政部不同意
     * @param gradeFlow 定级ID
     * @param personnel 人员名字
     * @param formReason 不同意的
     * @return
     */
    @Override
    public int staffingNoPass(OaGradeFlow gradeFlow, OaPersonnel personnel, String formReason) {
        // 又回到起点
        gradeFlow.setIsRevision("W");
        // 进度设置为起点审核
        gradeFlow.setGradeSchedule(GRADE_WRITE);

        int row=oaGradeFlowMapper.update(gradeFlow);

        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 薪资流程ID
        flowSchedule.setFlowId(GRADEDE_STAFFING);
        // 流程流程ID 部门审核节点
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 薪资流程ID
        flowSchedule.setFlowId(GRADEDE_STAFFING);
        // 绑定表单
        flowSchedule.setFormId(gradeFlow.getPkGradeId());
        // 人员ID
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        // 审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资交接流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        // 删除多余的通知
        messageMapper.deleteByFormId(gradeFlow.getPkGradeId());
        OaMessage message = new OaMessage();
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        // id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId(),
                flow.getGradeName(), "0");
        //通知填写人
        noPass(flow.getPersonnelId(),message.getPkMessageId());
        // 新建关联
        return row;
    }
    /**
     * 总经理通过
     *
     * @param gradeFlow 定级ID
     * @param personnel 操作人
     * @return 成功的数量
     */
    @Override
    public int executivePass(OaGradeFlow gradeFlow, OaPersonnel personnel) {

        //E为审核成功
        gradeFlow.setIsRevision("1");
        // 进度设置为结束审核
        gradeFlow.setGradeSchedule(GRADEDE_END);

        int row=oaGradeFlowMapper.update(gradeFlow);
        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 薪资流程ID
        flowSchedule.setFlowId(GRADEDE_EXECUTIVE);
        // 流程流程ID 部门审核节点
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 绑定表单
        flowSchedule.setFormId(gradeFlow.getPkGradeId());
        // 人员ID
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("");
        // 审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资交接流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        // 删除多余的通知
        messageMapper.deleteByFormId(gradeFlow.getPkGradeId());
        OaMessage message = new OaMessage();
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        //  4 已完成
        message.setPkMessageId(idToobtainUtils.getNumberId());
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId()
                , flow.getGradeName(), "4");

        noPass(flow.getPersonnelId(),message.getPkMessageId());
        // 新建关联
        return row;
    }


    @Override
    public OaGradeFlow isExist(OaPersonnel personnel) {
        return oaGradeFlowMapper.isExist(personnel.getPkPersonnelId());
    }

    /**
     * (批量删除之前备份数据)
     * @param list
     * @return
     */
    @Override
    public List<OaGradeFlow> selectAll(List<Long> list) {
        return oaGradeFlowMapper.selectAll(list);
    }

    /**
     * 部门审核不通过
     *
     * @param gradeFlow  定级ID
     * @param personnel  人员名字
     * @param formReason 不同意的
     * @return
     */
    @Override
    public int executiveNoPass(OaGradeFlow gradeFlow, OaPersonnel personnel, String formReason) {
        // 又回到起点
        gradeFlow.setIsRevision("W");
        // 进度设置为起点审核
        gradeFlow.setGradeSchedule(GRADE_WRITE);
        int row=oaGradeFlowMapper.update(gradeFlow);
        OaGradeFlow flow = oaGradeFlowMapper.selectByPrimaryKey(gradeFlow.getPkGradeId());
        //增加流程记录
        addFlowSchedule(GRADEDE_EXECUTIVE,gradeFlow.getPkGradeId(),personnel,formReason);
        // 删除多余的通知
        messageMapper.deleteByFormId(gradeFlow.getPkGradeId());
        OaMessage message = new OaMessage();
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/grade/gradeAudit.html?pkGradeId=");
        // id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        // 新增通知
        addMeassge(message, personnel.getPersonnelName(), flow.getPkGradeId(),
                flow.getGradeName(), "2");

        noPass(flow.getPersonnelId(),message.getPkMessageId());
        List<Long> personIds = personnelMapper.selectByHover("FRONT_WRITE");
        findPersons(personIds, message);

        // 新建关联
        return row;
    }

    /**
     * 添加流程记录
     * @param flowId 起草Id
     * @param gradeId 表单Id
     * @param personnel  流程操作人
     * @param formReason  操作人
     */
    public void addFlowSchedule(Long flowId,Long gradeId, OaPersonnel personnel,String formReason){
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录ID
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 起草id
        flowSchedule.setFlowId(flowId);
        // 绑定表单
        flowSchedule.setFormId(gradeId);
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 创建人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资定级记录
        flowScheduleMapper.insertSelective(flowSchedule);

    }    /**
     * 增加增加
     * @param message    通知
     * @param createdBy  创建人
     * @param pkGradeId  定级流程ID
     * @param messgeName 流程名
     * @param isRevision 有效性
     */
    public void addMeassge(OaMessage message, String createdBy, Long pkGradeId, String messgeName, String isRevision) {
        //创建人
        message.setCreatedBy(createdBy);
        //流程id
        message.setFormId(pkGradeId);
        // 通知标题
        message.setMessageName(messgeName);
        //状态
        message.setIsRevision(isRevision);
        // 新增通知
        messageMapper.insertSelective(message);
    }

    /**
     * 不通过的情况下或者通知个人
     * @param personnelId 人员idid
     * @param pkMessageId 通知
     */
    public void noPass(Long personnelId, Long pkMessageId) {
        //关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(personnelId);
        // 通知id
        inform.setMessageId(pkMessageId);
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);
    }

    /**
     * 通知人
     *
     * @param ids     通知人员的集合
     * @param message 通知
     */
    public void findPersons(List<Long> ids, OaMessage message) {
        if (ids.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : ids) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }
    }
}
